Most modern central processing units (CPUs) of computer systems allow the address space of the CPU ("logical address space") to have a different size than the available physical memory. These CPUs provide an address translation mechanism that translates the logical addresses to physical addresses that refer to locations in actual physical memory. Such address translation mechanisms are referred to as virtual memory systems. The virtual memory systems typically allow a larger logical address space than is physically available. The virtual memory systems also allow multiple programs to reside simultaneously in memory without each needing to know the location of its physical base address. Rather, such multiple programs need only know their logical base address.
FIG. 1 shows the paging portion of the virtual memory system of the Intel 80x86-family of processors. The 32-bit linear address 101, which is generated by the CPU, has a 12-bit offset 102 and a 20-bit page table index 103. The 80x86 page size is 4K bytes (2.sup.12) so the 12-bit offset is sufficient to access every location on a page. The page table 104 contains an entry for each page defined in the system. (The 80x86 actually uses a 2-tiered page table, but those details are not necessary to understand the present invention.) The entries contain a 20-bit page frame address 105, which is a base address of a corresponding page in physical memory. The virtual memory system translates a 32-bit linear address into a physical address in the following manner. The virtual memory system uses the page table index 103 as an index into the page table 104 to retrieve the page frame address stored in that entry. The physical address 108 is formed with the indexed page frame address 105 as the 20 high-order bits and the offset 102 as the 12 low-order bits. The physical address 108 points to a location in physical memory 109. In this example, there are 4 G (2.sup.32) addresses in the logical address space and 16 M (2.sup.24) physical memory locations.
When a computer system is first started up, the firmware in ROM typically checks physical memory to determine the limits of available physical address space. Typically, the firmware will write various test patterns to successive memory locations and then read the test patterns to ensure that the memory locations stored the test patterns correctly. When a memory location fails to store a value correctly, the firmware typically assumes that it either has ventured beyond the address range of installed memory or has encountered a malfunctioning (i.e., bad) memory location. Typically, the firmware then terminates memory testing and sets the amount of available memory to the lowest address of a bad memory location. For example, if a physical memory location at address 00FFE100 (addresses are shown in hexadecimal notation) is determined to be malfunctioning, then the firmware would set the amount of available memory to 00FFE100. Thus, memory locations at addresses 00000000 to 00FFE0FF would be available. The firmware then stores this information so that it can be retrieved by the operating system. When the operating system is started, it reads the information about available physical memory that was stored by the firmware. For an operating system that is able to utilize only a single contiguous area of physical memory, this would allow the operating system to store information at any memory location within the available memory, but would prevent the operating system from storing any data in physical memory at or above the first location that is bad. A downside, however, of setting the available memory to the lowest address of a bad location is that any good locations above (i.e., with higher addresses) that bad location are not accessible. Indeed, if an error occurred in the memory location in the first page of physical memory, then virtually all physical memory would be unavailable. In such a circumstance, it is likely that the operating system would not even be able to start.
Some operating systems do not encounter this problem because they are able to use non-contiguous portions of physical memory. For example, if a memory error occurs in one page of physical memory, the operating system simply marks that page as unavailable and is able to use all the other pages even though they may have higher physical memory addresses. The operating system simply maps logical addresses to physical addresses to avoid pages with bad memory locations. This mapping of pages is performed by using the page table of the CPU.
The high-order bits of the physical address from the CPU are decoded by a memory controller to produce selection signals, each of which activates a separate memory device. Some memory controllers provide a configurable assignment of the high-order physical address bits to the selected inputs of the memory devices, which effectively changes the base address of each memory device. FIG. 2 illustrates the decoding of the high-order bits of a physical address to the select inputs of the memory devices. (This is a highly simplified illustration; in particular, the splitting of the low-order address bits into row and column addresses and their subsequent multiplexing to the memory devices are not shown, since these operations are unrelated to the present invention.) The processor 201 outputs address lines A.sub.0 -A.sub.31. The low-order bits A.sub.0 -A.sub.21 are used to select an address within a selected 4 M memory device 203. Of the high-order bits A.sub.22 -A.sub.31, the least significant two, A.sub.22 -A.sub.23, are decoded by the decoder 202 into four separate select signals S.sub.0 -S.sub.3, which are in turn used to select one of the memory devices 203. Some memory controllers have a fixed assignment of address bit combinations to select signals, such that value 00 activates select signal 0, value 01 activates select signal 1, and so forth. However, if the memory controller supports configurable strobes, then the processor can modify this assignment. Thus, if the firmware detects that one of the memory devices is malfunctioning, then the firmware can map that memory device to the highest physical address and set the amount of available memory to exclude that memory device. A downside with such a mapping is that the granularity is limited to the size of a memory device, and therefore the memory locations above the lowest address of a bad memory location on a memory device are still unavailable. As memory devices grow in size, this limitation will become progressively more significant.